﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ACServerSelfHost
{
    public abstract class ConsoleCommand
    {
        protected abstract void ExecuteCommand(string toProcess);

        protected abstract string SyntaxDescription
        {
            get;
        }

        protected abstract ICollection<string> PossibleCommands();

        protected ConsoleCommand(string description)
        {
            Description = description;
        }

        public void Execute(string commandText)
        {
            ExecuteCommand(commandText);
        }

        public ICollection<string> Prefixes
        {
            get { return PossibleCommands(); }
        }
        public string Description { get; private set; }

        public override string ToString()
        {
            return string.Format(CultureInfo.CurrentCulture, "{0}\t{1}", SyntaxDescription, Description);
        }
    }

    public sealed class SimpleCommand : ConsoleCommand
    {
        private readonly List<string> commands = new List<string>();
        private readonly Action<string> action;

        public SimpleCommand(string description, IEnumerable<string> commands, Action<string> action)
            : base(description)
        {
            this.commands.AddRange(commands);
            this.action = action;
        }

        protected override void ExecuteCommand(string command)
        {
            action(command);
        }

        protected override ICollection<string> PossibleCommands()
        {
            return this.commands;
        }

        protected override string SyntaxDescription
        {
            get
            {
                string possibleForms = this.commands.First();
                if (this.commands.Count > 1 )
                {
                    possibleForms += " (" + string.Join(", ", this.commands.Skip(1)) + ")";
                }
                int l = possibleForms.Length;
                for (int i = 1; i <= (31 - l) / 8; i++)
                {
                    possibleForms += "\t";
                }
                return possibleForms;
            }
        }

    }

    class ConsoleCommandList : List<ConsoleCommand>
    {
        public ConsoleCommand FindByName(string command)
        {
            return this.FirstOrDefault(x => x.Prefixes.Any(command.StartsWith));
        }

        public override string ToString()
        {
            return this.Aggregate("Command (Alternative)\t\tDescription", (current, next) => current + Environment.NewLine + next);
        }
    }
}
